<!doctype html>
<html>
    <head>
        <title>Test Grid</title>
            
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
        
        <script src="./app.main.js"></script>
        <script src="./app.shapes.js"></script>
        <script src="./app.input.js"></script>
        <script src="./app.canvas.js"></script>
        <script>        
            
            app.Game = {
                rayLength: 100,
                gameWidth: 800,
                gameHeight: 640,
                scannerStepSize: 5,
                colorDeteroitateStepSize: 10
                
            }
            /**
             *Given 1 ray, find the shortest line from origin to intersection
             *
             *This should avoid overlapping issues like the far side of shapes or overlapping shapes by culling all but the shortest co-incident lines
             *
             */
            var intersects = function(ray, shape){
                    var candidate = false;
                    var cDist = ray.end.dist(ray.begin);
                    
                    $.each(shape, function(index, line){
                        var intersect = ray.intersect(line);
                        if( intersect[0] !== ray.INTERSECT){
                            return;
                        }
                        intersect = new appLib.Point(intersect[1], intersect[2]);
                        
                        var iDist = intersect.dist(ray.begin);
                        
                        if( iDist < cDist  ){
                            candidate = intersect;
                            cDist = iDist;
                        }                        
                        
                        
                    });
              
                    return candidate;
                };
            
        </script>
        <script type="text/javascript">
        var ctx;
                
                var pixelMap = function(){
                    var self  = this;
                    self.map = [];
                    
                    for(var y = 0; y < 800; y++){
                        map[y] = []                        
                        for(var x = 0; x < 640; x++){
                            map[y][x] = 0;
                        }
                        
                    }
                    
                    return {
                        add: function(p, value){
                            oldValue = self.map[Math.round(p.x)][Math.round(p.y)];
                            value = value + oldValue;
                            value = Math.min(512, Math.max(value, 0))
                            
                            self.map[Math.round(p.x)][Math.round(p.y)] = value;
                            
                        },
                        put: function(p, value){                            
                            value = Math.min(512, Math.max(value, 0))
                            
                            self.map[Math.round(p.x)][Math.round(p.y)] = value;
                        },
                        render: function(canvas){
                            var t60 = Math.PI * 2; //360 degrees as radian
                            canvas.save();
                                
                                canvas.beginPath();
                                
                            for(var x = 0; x < map.length; x++){
                                for(var y = 0; y < map.length; y++){
                                    var val = map[x][y];
                                    val = Math.max(Math.min(255, val),0)
                                    if(val > 0){
                                        //canvas.save();
                                        //canvas.beginPath();
                                    canvas.beginPath();
                                            canvas.moveTo(x,y);                                            
                                            canvas.fillStyle = "rgb(128," + val +",128)";
                                            canvas.arc(x, y, 1, 0, t60, false);
                                            canvas.closePath();
                                canvas.fill();
                                        
                                        
                                        map[x][y] = val - app.Game.colorDeteroitateStepSize;                                        
                                    }
                                }
                            }
                                
                            canvas.restore();
                        }
                    }
                    
                }();

                var shape1 = appLib.boxfactory(200, 300, 75);                
                
                //TODO research having other forms of line API                                
                var l5 = new appLib.Line(new appLib.Point(150, 340), new appLib.Point(640, 450)) ;
                //var shape1 = [l1, l2, l3, l4];                
                var shapes = [shape1, [l5]];
                
                
                var scanner = function(origin, radius){
                    
                    var radius = radius || app.Game.rayLength;
                    var step = app.Game.scannerStepSize;
                
                    for(var angle = 0; angle < 361 ; angle+= step){
                        if(angle % 2 == 0){
                            var p = ctx.ex.rayGen(radius, angle, origin.x, origin.y);    
                        }else{
                            var p = ctx.ex.rayGen(radius * .85 , angle, origin.x, origin.y);
                        }
                        
                        
                        var plotX = Math.min(ctx.canvas.width, p[0] );
                        var plotY = Math.min(ctx.canvas.height, p[1] );
                        var target  = new appLib.Point( plotX, plotY);
                        var castLine = new appLib.Line( origin, target ) ;
                                                
                        var toDraw = false;
                        var iDist = 1e1000;
                        
                        
                        //TODO - here is where a QuadTree or such might come in handy
                        $.each(shapes, function(index, shape){
                            var intersect = intersects(castLine, shape);
                                                                                                            
                            if(intersect !== false){
                                //We hit something so increase resolution
                                step = 0.5;
                                var test = new appLib.Line(origin, intersect);
                                var tDist = test.dist();
                                if(tDist < iDist ){
                                    toDraw = new appLib.Line(origin, intersect);
                                    iDist = tDist;
                                }
                                
                            }else{
                                step = Math.min(5, step * 2);
                            }                            
                        });                        
                        
                        if(toDraw !== false){                            
                            //ctx.line(toDraw.begin, toDraw.end);
                            //pixelMap.put(toDraw.end, 250);
                            pixelMap.add(toDraw.end, 45);
                        }
                    }
                                        
                };
                
                var clearCanvas = function(ctx){
                    ctx.beginPath();
                    
                        ctx.clearRect(0,0, 800, 640);
                        ctx.rect(0,0, 800, 640);
                        ctx.fillStyle = "black";  //BUG fix - something is eating the save-restore pattern for FF
                        ctx.fill();
                    ctx.closePath();
                }
                
                var origin = new appLib.Point(0, 0);
                
                var mouseHandler = function(evt){
                    origin = new appLib.Point(evt.layerX - evt.currentTarget.offsetLeft, evt.layerY - evt.currentTarget.offsetTop);
                    
                };
                
                var eventHandler = function(){
                    clearCanvas(ctx);
                    scanner(origin, 0);
                    //pixelMap.add(origin, 120);
                    ctx.save();
                    //ctx.line(new appLib.Point(150, 340), new appLib.Point(640, 450));
                    
                    ctx.strokeStyle = "white";
                    
                    ctx.beginPath();
                        ctx.arc(origin.x, origin.y, app.Game.rayLength, 0, Math.PI * 2, false);
                    ctx.closePath();
                    ctx.stroke();
                    
                    
                    pixelMap.render(ctx);
                }
                
                                
          
            $(function(){
                ctx = document.getElementById("myCan").getContext("2d");
                $('#myCan').mousemove(mouseHandler);
                setInterval(eventHandler, 10);
                               
            });
                                
                            
        </script>
    </head>
    <body>
        <canvas id="myCan" style="border:thin black solid"  height=640 width=800>If you can see this, your browser is behind the times</canvas>
        
    </body>
</html>